package com.itcam.otcbackend.auth;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.itcam.otcbackend.auth.model.SpaceUserAuthConfig;
import com.itcam.otcbackend.auth.model.SpaceUserRole;
import com.itcam.otcbackend.enums.SpaceRoleEnum;
import com.itcam.otcbackend.enums.SpaceTypeEnum;
import com.itcam.otcbackend.model.po.Space;
import com.itcam.otcbackend.model.po.SpaceUser;
import com.itcam.otcbackend.model.po.User;
import com.itcam.otcbackend.service.SpaceUserService;
import com.itcam.otcbackend.service.UserService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 空间用户认证管理器，用于管理空间用户的认证配置和权限获取
 */
@Component
public class SpaceUserAuthManager {

    /**
     * 空间用户服务，用于处理空间用户相关业务逻辑
     */
    @Resource
    private SpaceUserService spaceUserService;

    /**
     * 用户服务，用于处理用户相关业务逻辑
     */
    @Resource
    private UserService userService;

    /**
     * 静态常量，存储空间用户认证配置
     */
    public static final SpaceUserAuthConfig SPACE_USER_AUTH_CONFIG;

    /**
     * 静态代码块，在类加载时初始化 SPACE_USER_AUTH_CONFIG
     */
    static {
        // 读取 biz/spaceUserAuthConfig.json 文件内容，使用 UTF-8 编码
        String json = ResourceUtil.readUtf8Str("biz/spaceUserAuthConfig.json");
        // 将 JSON 字符串转换为 SpaceUserAuthConfig 对象
        SPACE_USER_AUTH_CONFIG = JSONUtil.toBean(json, SpaceUserAuthConfig.class);
    }

    /**
     * 根据角色获取权限列表
     *
     * @param spaceUserRole 空间用户角色的字符串表示
     * @return 该角色对应的权限列表，如果角色为空或未找到匹配角色，则返回空列表
     */
    public List<String> getPermissionsByRole(String spaceUserRole) {
        // 检查传入的角色是否为空或空白字符串
        if (StrUtil.isBlank(spaceUserRole)) {
            // 如果为空，返回一个空的 ArrayList
            return new ArrayList<>();
        }
        // 从配置中找到匹配的角色
        SpaceUserRole role = SPACE_USER_AUTH_CONFIG.getRoles().stream()
                // 过滤出与传入角色键匹配的角色
                .filter(r -> spaceUserRole.equals(r.getKey()))
                // 获取第一个匹配的角色
                .findFirst()
                // 如果未找到匹配的角色，返回 null
                .orElse(null);
        // 检查是否找到匹配的角色
        if (role == null) {
            // 如果未找到，返回一个空的 ArrayList
            return new ArrayList<>();
        }
        // 返回匹配角色的权限列表
        return role.getPermissions();
    }

    /**
     * 根据给定的空间和登录用户，获取该用户在该空间的权限列表。
     *
     * @param space     空间对象，可为 null，表示公共图库
     * @param loginUser 登录用户对象，可为 null
     * @return 该用户在该空间的权限列表，如果用户无权限或出现异常，返回空列表
     */
    public List<String> getPermissionList(Space space, User loginUser) {
        // 如果登录用户为空，直接返回空权限列表
        if (loginUser == null) {
            return new ArrayList<>();
        }
        // 获取管理员角色的权限列表
        List<String> ADMIN_PERMISSIONS = getPermissionsByRole(SpaceRoleEnum.ADMIN.getValue());
        // 若空间为空，表示公共图库
        if (space == null) {
            // 检查登录用户是否为管理员
            if (userService.isAdmin(loginUser)) {
                // 若是管理员，返回管理员权限列表
                return ADMIN_PERMISSIONS;
            }
            // 若不是管理员，返回空权限列表
            return new ArrayList<>();
        }
        // 根据空间类型值获取对应的枚举类型
        SpaceTypeEnum spaceTypeEnum = SpaceTypeEnum.getEnumByValue(space.getSpaceType());
        // 若未找到对应的空间类型枚举，返回空权限列表
        if (spaceTypeEnum == null) {
            return new ArrayList<>();
        }
        // 根据空间类型枚举，判断不同的空间类型
        switch (spaceTypeEnum) {
            case PRIVATE:
                // 私有空间，仅本人或管理员有所有权限
                // 检查空间的用户ID是否与登录用户ID相同，或者登录用户是否为管理员
                if (space.getUserId().equals(loginUser.getId()) || userService.isAdmin(loginUser)) {
                    // 若满足条件，返回管理员权限列表
                    return ADMIN_PERMISSIONS;
                } else {
                    // 若不满足条件，返回空权限列表
                    return new ArrayList<>();
                }
            case TEAM:
                // 团队空间，查询 SpaceUser 并获取角色和权限
                // 根据空间ID和用户ID查询对应的 SpaceUser 对象
                SpaceUser spaceUser = spaceUserService.lambdaQuery()
                        .eq(SpaceUser::getSpaceId, space.getId())
                        .eq(SpaceUser::getUserId, loginUser.getId())
                        .one();
                // 若未找到对应的 SpaceUser 对象，返回空权限列表
                if (spaceUser == null) {
                    return new ArrayList<>();
                } else {
                    // 若找到对应的 SpaceUser 对象，根据其角色获取权限列表
                    return getPermissionsByRole(spaceUser.getSpaceRole());
                }
        }
        // 若以上条件都不满足，返回空权限列表
        return new ArrayList<>();
    }

}

